package merchant

import (
	"context"
	"encoding/json"
	"strings"
	"time"

	"system-admin/config/mysql"
	"system-admin/config/redis"
	"system-admin/internal/define"
	"system-admin/internal/models"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/helper"
)

// MerchantDetail 商户详情
func MerchantDetail(merchantID string) (merchant models.Merchant, err error) {
	rowsAffected := mysql.NewDB().
		Model(&models.Merchant{}).
		Where("id = ?", merchantID).
		Take(&merchant).RowsAffected
	if rowsAffected == 0 {
		return merchant, errorx.New("商户不存在", -1)
	}
	return merchant, nil
}

// AllMerchant 获取全部商户
func AllMerchant(loginUserID, loginMerchantID string, fields string, page, limit int) (merchants []models.Merchant, total int64) {
	if fields == "" {
		fields = "id,name"
	}
	// 获取当前登录用户的商户id
	var user models.User
	if loginMerchantID == "" {
		mysql.NewDB().Model(&models.User{}).Where("id = ?", loginUserID).Take(&user)
		loginMerchantID = user.MerchantID
	}
	// 获取商户信息
	var merchantRecord models.Merchant
	mysql.NewDB().Model(&models.Merchant{}).Where("id = ?", loginMerchantID).Take(&merchantRecord)

	// 获取商户记录
	tx := mysql.NewDB().Model(&models.Merchant{})
	if loginMerchantID != "1" {
		tx = tx.Where(
			"merchant_path LIKE ? OR id = ?",
			merchantRecord.MerchantPath+">"+merchantRecord.ID+"%",
			merchantRecord.ID,
		)
	}
	tx = tx.Where("deleted_at = ?", 0)
	tx.Count(&total)
	tx = helper.Gorm{}.Paginate(tx, page, limit)
	tx.Select(strings.Split(fields, ",")).
		Order("id asc").
		Find(&merchants)
	return merchants, total
}

// 商户列表
func MerchantList(loginUserID string, merchantName string, page, limit int) (interface{}, int64) {
	var merchants []struct {
		models.Merchant
		AdminUser string `json:"admin_user" gorm:"column:admin_user"`
		RoleID    string `json:"role_id" gorm:"column:role_id"`
		RoleName  string `json:"role_name" gorm:"column:role_name"`
	}
	db := mysql.NewDB()

	// 获取登录用户的信息
	var loginUser models.User
	db.Model(&models.User{}).Where("id = ?", loginUserID).Take(&loginUser)

	// 公共条件
	tx := db.Model(&models.Merchant{}).
		Joins("LEFT JOIN user ON user.id = merchant.admin_user_id").
		Joins("LEFT JOIN role ON role.id = user.role_id").
		Where("merchant.pid = ?", loginUser.MerchantID).
		Where("merchant.deleted_at = ?", 0)

	merchantName = strings.TrimSpace(merchantName)
	if merchantName != "" {
		tx.Where("merchant.name LIKE ?", "%"+merchantName+"%")
	}

	// 商户数量
	var count int64
	tx.Count(&count)

	// 商户列表
	helper.Gorm{}.Paginate(tx, page, limit).
		Select(
			"merchant.id",
			"merchant.name",
			"merchant.contact_user",
			"merchant.contact_phone",
			"merchant.contact_addr",
			"merchant.api_token",
			"merchant.updated_at",
			"user.username as admin_user",
			"user.role_id",
			"role.name as role_name",
		).
		Find(&merchants)
	// 没有token的自动补充token
	for index, merchant := range merchants {
		if merchant.APIToken == "" {
			token := helper.RandString(32)
			mysql.NewDB().Model(&models.Merchant{}).
				Where("id = ?", merchant.ID).
				Update("api_token", token)
		}

		// 不是管理员的不显示token
		if loginUser.IsSuperAdmin != 1 {
			merchants[index].APIToken = ""
		}
	}

	return merchants, count
}

// 新增商户
func AddMerchant(loginUserID, merchantName, contactUser, contactPhone, contactAddr string) (string, error) {
	db := mysql.NewDB()

	// 参数检查
	if strings.TrimSpace(merchantName) == "" {
		return "", errorx.New("商户名不能为空", -1)
	}

	// 获取登录用户的信息
	var userInfo struct {
		MerchantID   string `gorm:"column:merchant_id"`
		MerchantPath string `gorm:"column:merchant_path"`
	}
	{
		rowsAffected := db.Model(&models.User{}).
			Joins("Left JOIN merchant ON user.merchant_id=merchant.id").
			Select(
				"user.merchant_id",
				"merchant.merchant_path",
			).
			Where("user.id = ?", loginUserID).
			Take(&userInfo).
			RowsAffected
		if rowsAffected <= 0 || (userInfo.MerchantID != "1" && userInfo.MerchantPath == "") {
			return "", errorx.New("请重新登录", 40307)
		}
	}

	// 判断用户名是否存在
	{
		var count int64
		db.Model(&models.Merchant{}).Where("name = ?", merchantName).Count(&count)
		if count > 0 {
			return "", errorx.New("商户名已存在", -1)
		}
	}

	// 新增
	var merchant models.Merchant
	merchant.Name = merchantName
	merchant.ContactUser = contactUser
	merchant.ContactPhone = contactPhone
	merchant.ContactAddr = contactAddr
	merchant.PID = userInfo.MerchantID
	merchant.MerchantPath = strings.Join([]string{userInfo.MerchantPath, userInfo.MerchantID}, ">")
	if len(merchant.MerchantPath) > 200 {
		return "", errorx.New("商户层级过多", -1)
	}
	rowsAffected := db.Model(&models.Merchant{}).Create(&merchant).RowsAffected
	if rowsAffected <= 0 {
		return "", errorx.New("新增商户失败", -1)
	}
	// 更新缓存
	LoadMerchantToRedis()
	return merchant.ID, nil
}

// 编辑商户
func EditMerchant(loginUserID, merchantID, merchantName, contactUser, contactPhone, contactAddr string) error {
	db := mysql.NewDB()
	// 编辑权限检查
	editAuthCheck(loginUserID, merchantID)
	// 判断商户是否存在
	var count int64
	db.Model(&models.Merchant{}).Where("id = ?", merchantID).Count(&count)
	if count <= 0 {
		return errorx.New("商户不存在", -1)
	}

	// 判断商户名是否已存在
	if merchantName != "" {
		var merchant models.Merchant
		rowsAffected := db.Model(&models.Merchant{}).Where("name = ?", merchantName).Take(&merchant).RowsAffected
		if rowsAffected > 0 && merchant.ID != merchantID {
			return errorx.New("商户名已存在", -1)
		}
	}

	// 编辑
	var merchant models.Merchant
	merchant.Name = merchantName
	merchant.ContactUser = contactUser
	merchant.ContactPhone = contactPhone
	merchant.ContactAddr = contactAddr
	rowsAffected := db.Model(&models.Merchant{}).
		Where("id = ?", merchantID).
		Updates(&merchant).
		RowsAffected
	if rowsAffected <= 0 {
		return errorx.New("编辑商户失败", -1)
	}
	// 更新缓存
	LoadMerchantToRedis()
	return nil
}

// 删除商户
// 伪删除，避免相关资源无法访问
// 登录时要检测商户的状态，已删除商户的用户提示禁用
func DeleteMerchant(loginUserID string, merchantID string) error {
	db := mysql.NewDB()
	// 编辑权限检查
	editAuthCheck(loginUserID, merchantID)
	// 判断商户是否存在
	var count int64
	db.Model(&models.Merchant{}).Where("id = ?", merchantID).Count(&count)
	if count <= 0 {
		return errorx.New("商户不存在", -1)
	}
	tx := db.Begin()
	// 删除商户
	rowsAffected := tx.Model(&models.Merchant{}).
		Where("id = ?", merchantID).
		Update("deleted_at", time.Now().Unix()).
		RowsAffected
	if rowsAffected <= 0 {
		tx.Rollback()
		return errorx.New("商户删除失败", -1)
	}

	// 禁用商户下的用户
	err := tx.Model(&models.User{}).Where(&models.User{MerchantID: merchantID}).Update("status", 2).Error
	if err != nil {
		tx.Rollback()
		return errorx.New("用户禁用失败", -1)
	}
	tx.Commit()
	// 更新缓存
	LoadMerchantToRedis()
	return nil
}

// editAuthCheck 编辑权限检查
func editAuthCheck(loginUserID string, merchantID string) error {
	var loginUser models.User
	db := mysql.NewDB()
	// 获取登录用户的信息
	rowsAffected := db.Model(&models.User{}).Where("id = ?", loginUserID).Take(&loginUser).RowsAffected
	if rowsAffected <= 0 {
		return errorx.New("请重新登录", 40307)
	}
	// 获取要编辑的商户的信息
	var merchant models.Merchant
	{
		rowsAffected := db.Model(&models.Merchant{}).Where("id = ?", merchantID).Take(&merchant).RowsAffected
		if rowsAffected <= 0 {
			return errorx.New("商户不存在", -1)
		}
	}
	// 判断要编辑的商户是否为当前用户的商户创建的
	if loginUser.MerchantID != merchant.PID {
		return errorx.New("无权限", -1)
	}
	return nil
}

// 加载商户信息到redis
func LoadMerchantToRedis() {
	var merchants []struct {
		ID           string `json:"-" gorm:"column:id"`
		PID          string `json:"pid" gorm:"column:pid"`
		Name         string `json:"name" gorm:"column:name"`
		MerchantPath string `json:"merchant_path" gorm:"column:merchant_path"`
	}
	mysql.NewDB().Model(&models.Merchant{}).
		Select(
			"id",
			"pid",
			"name",
			"merchant_path",
		).
		Find(&merchants)

	var values []interface{}
	for _, merchant := range merchants {
		dataBytes, _ := json.Marshal(merchant)
		values = append(values, merchant.ID, string(dataBytes))
	}
	redis.NewDB().HMSet(context.Background(), define.RedisMerchantList, values...)
}
